home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / mg_comm.com / COMM.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-03-13  |  6.7 KB  |  298 lines

  1. #include <stdio.h>
  2. #include <conio.h>
  3. #include <dos.h>
  4. #include "comm.h"
  5.  
  6. /* See the COMM.H file for documentation on functions */
  7.  
  8. /*  M_I86 is predefined in Microsoft C, but not Turbo, with this information
  9. **  we can use the following code to create portable code
  10. */
  11. #ifdef M_I86
  12.      /*  For MicroSoft C  */
  13.     #include <malloc.h>
  14.    #define SetVect(x,y) _dos_setvect(x,y)
  15.    #define GetVect(x)   _dos_getvect(x)
  16.    #define Enable()     _enable()
  17.    #define Disable()    _disable()
  18. #else
  19.     /*   For Turbo C */
  20.     #include <alloc.h>
  21.    #define SetVect(x,y) setvect(x,y)
  22.    #define GetVect(x)   getvect(x)
  23.    #define Enable()     enable()
  24.    #define Disable()    disable()
  25. #endif
  26.  
  27.  
  28. int _int_port;  /* 1 for COM1, 2 for COM2, etc...  */
  29. int BufSize=4096;
  30.  
  31. volatile char *_icbuffer, *HeadP, *TailP, *BuffEnd, *BufBeg;
  32.  
  33. /****************************************/
  34. /*  Serial interupt data & declarations */
  35. /****************************************/
  36. struct _COMPORT_ {
  37.         int BasePort, IntMask, Intr;
  38.         } ComPort[]={ 
  39.             0x3F8, 0xEF, 0x0C,
  40.             0x2F8, 0xF7, 0x0B
  41.             };
  42.     /* Input and output Ports */
  43. #define InPort(x)    (ComPort[x].BasePort)
  44. #define OutPort(x)   (ComPort[x].BasePort)
  45.     /* Baud rate divisors */
  46. #define BaudL(x)     (ComPort[x].BasePort)
  47. #define BaudH(x)     (ComPort[x].BasePort+1)
  48.     /* Interrupt enable, and ID ports */
  49. #define IntEnable(x) (ComPort[x].BasePort+1)
  50. #define IntID(x)     (ComPort[x].BasePort+2)
  51.     /* Lince Control register, and Modem Control Register */
  52. #define LCReg(x)     (ComPort[x].BasePort+3)
  53. #define MCReg(x)     (ComPort[x].BasePort+4)
  54.     /* Lines Status and Modem Status registers */
  55. #define LStatus(x)   (ComPort[x].BasePort+5)
  56. #define MStatus(x)   (ComPort[x].BasePort+6)
  57.     /* Interrupt mask and number */
  58. #define IntMask(x)   (ComPort[x].IntMask)
  59. #define Intr(x)      (ComPort[x].Intr)
  60.  
  61. void (interrupt far *Serial)();  /* for origninal serial int. */
  62.  
  63. void interrupt far Handler(void);
  64.  
  65. /****************************************/
  66. /*  The actual serial interface driver  */
  67. /****************************************/
  68. void interrupt far Handler()
  69. {
  70.     Disable();
  71.  
  72.     *TailP++=(char)inp(InPort(_int_port));
  73.     if (TailP==BuffEnd)
  74.        TailP=BufBeg;
  75.     if (TailP==HeadP) {
  76.        HeadP++;
  77.        if (HeadP==BuffEnd)
  78.           HeadP=BufBeg;
  79.        }
  80.  
  81.     Enable();
  82.     outp(0x20, 0x20);   /* send an end of interrupt signal to hardare */
  83. }
  84. /******END OF SERIAL INTERUPT***************/
  85.  
  86.  
  87. /*****************************************/
  88. /*     SET & RESET SERIAL INTERUPT       */
  89. /*****************************************/
  90. int SetIntr(int cport)
  91. {
  92.     unsigned i;
  93.     if((_icbuffer=malloc(BufSize))==NULL)
  94.         return(-1);
  95.     BufBeg=_icbuffer;
  96.     BuffEnd=_icbuffer+BufSize;
  97.     TailP=HeadP=BufBeg;
  98.     if (inp(InPort(cport))==0xFF && inp(LStatus(cport))==0xFF && inp(LCReg(cport))==0xFF)
  99.        return(-1);   /* no UART found at port address */
  100.  
  101.      /* install the handler  */
  102.     _int_port=cport;
  103.     Serial=GetVect(Intr(cport));
  104.     SetVect(Intr(cport), Handler);    /* point to our handler  */
  105.     
  106.              /*  set up the interupt controller  */
  107.  
  108.     outp(MCReg(cport), 0xB);   /* set OUT2, DTR, & RTS on UART  */
  109.     outp(IntEnable(cport), 1);     /* set interupt enable reg on UART to data ready */
  110.     i=inp(0x21);                  /* setup interupt controller chip  */
  111.     i= (i & IntMask(cport));
  112.     outp(0x21, i);
  113.     return(0);
  114. }
  115.  
  116.  
  117. void ResetIntr(int cport)
  118. {
  119.     int i,j;
  120.     /* first disable the interupts via interrupt mask on PIC chip */
  121.  
  122.     free(_icbuffer);
  123.     i=~IntMask(cport);
  124.     j=inp(0x21);
  125.     j=j | i;
  126.     /* outp(0x21, j); */
  127.  
  128.     /*  then restore the original serial intr pointer  */
  129.  
  130.     SetVect(Intr(cport), Serial);
  131. }
  132.  
  133. /*******************************************/
  134. /*         recieve to COM? functions       */
  135. /*******************************************/
  136. int GetSer()
  137. {
  138.     int ch;
  139.  
  140.     ch=*HeadP++;
  141.     if (HeadP==BuffEnd)
  142.        HeadP=BufBeg;
  143.     return(ch);
  144. }
  145.  
  146.  
  147. /******************************************/
  148. /* func to init COM? to correct settings  */
  149. /* returns a -1 if port not there,        */
  150. /*           -2 if invalid parameter      */
  151. /*            0 if ok                     */
  152. /******************************************/
  153.  
  154. int PortInit(int cport, int baud, int parity, int data, int stop)
  155. {
  156.  
  157.     unsigned char attrib=0;
  158.     char temp;
  159.     int cbaud;
  160.  
  161.  
  162.     /* these items setup the attribute bits for the byte to be sent
  163.        to the UART (data bits, stop bits, etc.)  */
  164.  
  165.     if (inp(InPort(cport))==0xFF && inp(LStatus(cport))==0xFF && inp(LCReg(cport))==0xFF)
  166.        return(-1);   /* no UART found at port address */
  167.  
  168.  
  169.     if (cport>0x0001|| parity>2 || data>8 || stop>2)
  170.        return(-2);
  171.     if (parity != 0) {
  172.        if (parity==1)
  173.           attrib=8;
  174.        else
  175.           attrib=24;
  176.        }
  177.     if (stop>1)
  178.        attrib=attrib+4;
  179.     attrib+= (unsigned char)(data-5);
  180.     cbaud=0;
  181.     if (baud==19200)
  182.        cbaud=6;
  183.     else
  184.      if (baud==9600)
  185.         cbaud=0xC;
  186.      else
  187.        if (baud==4800)
  188.           cbaud=0x18;
  189.        else
  190.           if (baud==2400)
  191.              cbaud=0x30;
  192.           else
  193.              if (baud==1200)
  194.                 cbaud=0x60;
  195.              else
  196.                 if (baud==300)
  197.                    cbaud=0x180;
  198.                 else
  199.                    return(-2);
  200.     
  201.     outp(LCReg(cport), (unsigned) 0x80);
  202.     outp(BaudL(cport), cbaud%0x100);
  203.     outp(BaudH(cport), cbaud/0x100);
  204.     outp(LCReg(cport), attrib);
  205.     
  206.     return(0);
  207. }
  208.  
  209. void ClearBuffer()       /* clear communications buffer */
  210. {
  211.     HeadP=TailP=BufBeg;
  212. }
  213.  
  214.  
  215. void Xmit(char ch)
  216. {
  217.   while ( ((inp(LStatus(_int_port))) & 0x20 ) ==0)
  218.         ;
  219.   outp(OutPort(_int_port), ch);
  220. }
  221.  
  222. void SendStr(char *str)
  223. {
  224.     while (*str)  {
  225.        if (*str == '|')
  226.           Xmit(13);
  227.        else if (*str=='~')  {
  228.           OneSec();
  229.           }
  230.        else
  231.           Xmit(*str);
  232.        str++;
  233.        }
  234. }
  235.  
  236. int SerAvl()
  237. {
  238.     return(HeadP-TailP);
  239. }
  240.  
  241. int IsCarrier(int cport)
  242. {
  243.     int i;
  244.  
  245.     i=inp(MStatus(cport));
  246.     return(i&0x80);
  247. }
  248.  
  249. void OneSec()
  250. {
  251.     union REGS regin, regout;
  252.  
  253.     unsigned int dest;
  254.  
  255.     regin.h.ah=0;
  256.     int86(0x1A, ®in, ®out);
  257.     dest=regout.x.dx+18;
  258.     while( (unsigned) regout.x.dx < dest) {
  259.        regin.h.ah=0;
  260.        int86( 0x1A, ®in, ®out);
  261.       }
  262. }
  263.     
  264. void Delay(int len)
  265. {
  266.     union REGS regin, regout;
  267.  
  268.     unsigned int dest;
  269.  
  270.     regin.h.ah=0;
  271.     int86(0x1A, ®in, ®out);
  272.     dest=regout.x.dx+len;
  273.     while( (unsigned) regout.x.dx < dest) {
  274.        regin.h.ah=0;
  275.        int86( 0x1A, ®in, ®out);
  276.        }
  277. }
  278.  
  279. int ModemStatus()
  280. {
  281.     return(MStatus(_int_port));
  282. }
  283.  
  284. void HWHangup()
  285. {
  286.     int i;
  287.     i=inp(MCReg(_int_port));
  288.     i=i&0xFE;
  289.     outp(MCReg(_int_port), 0);  /* all bits off, then on, then normal */
  290.     inp(MCReg(_int_port));
  291.     outp(MCReg(_int_port), 0xFF);
  292.     inp(MCReg(_int_port));
  293.     outp(MCReg(_int_port), i);
  294.     OneSec();
  295.     i=i|1;
  296.     outp(MCReg(_int_port), i);
  297. }
  298.